---
title: Password Input
description: Used to request or confirm a password from users.
package: "@zag-js/password-input"
---

<Resources pkg="@zag-js/password-input" />

<Showcase id="PasswordInput" />

**Features**

- Includes button to toggle visibility of the password
- Automatic focus restoration to the input
- Resets visibility to hidden after form submission
- Ignore password management apps like 1Password, LastPass, etc.

## Installation

To use the password-input machine in your project, run the following command in
your command line:

<CodeSnippet id="password-input/installation.mdx" />

## Anatomy

To set up the password-input correctly, you'll need to understand its anatomy
and how we name its parts.

> Each part includes a `data-part` attribute to help identify them in the DOM.

<Anatomy id="password-input" />

## Usage

First, import the password-input package into your project

```jsx
import * as passwordInput from "@zag-js/password-input"
```

The password-input package exports two key functions:

- `machine` — The state machine logic for the password-input widget.
- `connect` — The function that translates the machine's state to JSX attributes
  and event handlers.

> You'll also need to provide a unique `id` to the `useMachine` hook. This is
> used to ensure that every part has a unique identifier.

Next, import the required hooks and functions for your framework and use the
password-input machine in your project 🔥

<CodeSnippet id="password-input/usage.mdx" />

### Setting the initial visibility

Use the `defaultVisible` context property to set the initial visibility of the
password input.

```tsx {3}
const service = useMachine(passwordInput.machine, {
  id: useId(),
  defaultVisible: true,
})
```

### Controlling the visibility

Use the `visible` and `onVisibilityChange` context properties to control the
visibility of the password input.

> The `onVisibilityChange` callback is invoked when the visibility changes.

```tsx {3-5}
const service = useMachine(passwordInput.machine, {
  id: useId(),
  visible: true,
  onVisibilityChange(details) {
    console.log(details)
  },
})
```

### Ignoring password managers

Set the `ignorePasswordManager` context property to `true` to ignore password
managers like 1Password, LastPass, etc.

This is useful when you want to ensure that the password input is not managed by
password managers. **Currently, this only works for 1Password, LastPass,
Bitwarden, Dashlane, and Proton Pass.**

```tsx {3}
const service = useMachine(passwordInput.machine, {
  id: useId(),
  ignorePasswordManager: true,
})
```

**Why is this useful?**

- You might want to use this primitive for non-login scenarios (e.g., "secure
  notes", "temporary passwords")

- In a verify password step, you might want to disable password managers for the
  confirm password field to ensure manual entry

- Building a security-sensitive app where password managers violate compliance
  requirements.

### Managing autocompletion

Configure the `autoComplete` context property to manage autocompletion.

- `new-password` — The user is creating a new password.
- `current-password` — The user is entering an existing password.

```tsx {3}
const service = useMachine(passwordInput.machine, {
  id: useId(),
  autoComplete: "new-password",
})
```

### Making the input required

Set the `required` context property to `true` to make the input required.

```tsx {3}
const service = useMachine(passwordInput.machine, {
  id: useId(),
  required: true,
})
```

### Making the input read only

Set the `readOnly` context property to `true` to make the input read only.

```tsx {3}
const service = useMachine(passwordInput.machine, {
  id: useId(),
  readOnly: true,
})
```

## Styling guide

Earlier, we mentioned that each password-input part has a `data-part` attribute
added to them to select and style them in the DOM.

```css
[data-scope="password-input"][data-part="root"] {
  /* styles for the root part */
}

[data-scope="password-input"][data-part="input"] {
  /* styles for the input part */
}

[data-scope="password-input"][data-part="visibility-trigger"] {
  /* styles for the visibility trigger part */
}

[data-scope="password-input"][data-part="indicator"] {
  /* styles for the indicator part */
}

[data-scope="password-input"][data-part="control"] {
  /* styles for the control part */
}

[data-scope="password-input"][data-part="label"] {
  /* styles for the label part */
}
```

### Visibility State

Use the `[data-state="visible"]` and `[data-state="hidden"]` attributes to style
the password input when it is visible or hidden.

```css
[data-scope="password-input"][data-part="input"][data-state="visible"] {
  /* styles for the visible state (for input) */
}

[data-scope="password-input"][data-part="visibility-trigger"][data-state="visible"] {
  /* styles for the visible state (for visibility trigger) */
}
```

### Disabled State

Use the `[data-disabled]` attribute to style the password input when it is
disabled.

```css
[data-scope="password-input"][data-part="input"][data-disabled] {
  /* styles for the disabled state */
}
```

### Invalid State

Use the `[data-invalid]` attribute to style the password input when it is
invalid.

```css
[data-scope="password-input"][data-part="input"][data-invalid] {
  /* styles for the invalid state */
}
```

### Readonly State

Use the `[data-readonly]` attribute to style the password input when it is read
only.

```css
[data-scope="password-input"][data-part="input"][data-readonly] {
  /* styles for the readonly state */
}
```

## Methods and Properties

### Machine Context

The password-input machine exposes the following context properties:

<ContextTable name="password-input" />

### Machine API

The password-input `api` exposes the following methods:

<ApiTable name="password-input" />
